package com.cilico.utils;

import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.GradientDrawable.Orientation;
import android.graphics.drawable.shapes.RectShape;
import android.graphics.drawable.shapes.RoundRectShape;

/**
 * 画笔绘制
 * @author lv.xiangan
 *
 */
public final class DrawableFactory {

	/**
	 * styleIndex=’0’ -- 普通直角框
	 * 
	 * styleIndex=’1’ -- 圆角框，外框线带有颜色渐变。 Need the height.
	 * 
	 * styleIndex=’2’ -- 普通圆角框
	 * 
	 * styleIndex=’3’ -- 圆角框，边框内侧带有颜色渐变，视觉上有下凹感觉
	 * 
	 * styleIndex=’4’ -- 圆角框，框内背景色有渐变，视觉上有凸起感觉
	 * 
	 * styleIndex=’5’ -- 圆角框，框内背景色有渐变，颜色渐变没有5柔和，会以框的中线为分割，有明显得颜色变化，视觉上有凸起感觉
	 * 
	 * styleIndex=’6’ -- 圆角框，框内背景色有渐变，底部有阴影，视觉上有凸起感觉，整体感觉最立体的一种样式
	 * 
	 * @param styleIndex
	 * @param rect
	 * @param color
	 * @param borderColor
	 * @param isPressedDown
	 * @return
	 */
	public static final Drawable[] create(int styleIndex, Rect rect, int color, int borderColor, boolean isPressedDown) {
		Drawable[] sds = null;
		switch (styleIndex) {
		case 0:
			sds = normalRect(color, rect);
			break;
		case 1:
			sds = roundRectWithGradientBorder(color, borderColor, rect);
			break;
		case 2:
			sds = roundRect(color, rect);
			break;
		case 3:
			sds = roundRectConcave(color, borderColor, rect);
			break;
		case 4:
			sds = roundRectGradient(color, rect);
			break;
		case 5:
			sds = roundRectStereo(color, rect);
			break;
		case 6:
			sds = roundRectStereoWithShader(color, rect, isPressedDown);
			break;
		default:
			break;
		}
		return sds;
	}

	private static final int CORNER_RADIUS = 10;
	private static final float[] alpha_ = new float[] { 0.685f, 0.13f, 0.27f };
	private static final int[] alphaTop_ = new int[] { ((int) (0xff * alpha_[0]) << 24) + 0x00ffffff, ((int) (0xff * alpha_[1]) << 24) + 0x00ffffff };
	private static final int[] alphaBottom_ = new int[] { 0x00ffffff, ((int) (0xff * alpha_[2]) << 24) + 0x00ffffff };
	private static final float[] locations_ = new float[] { 0.5f, 0.6f };
	private static final float HORIZONTAL_BORDER = 3;
	private static final float VERTICAL_BORDER = 3;
	private static final int SHADOW_HOR_OFFSET = 2;
	private static final int SHADOW_VER_OFFSET = 2;
	private static final int SHADER_COLOR = 0xff6e6e63;

	/**
	 * styleIndex=’0’ -- 普通直角框
	 * 
	 * @param color
	 * @param rect
	 * @return
	 */
	private static final ShapeDrawable[] normalRect(int color, Rect rect) {
		ShapeDrawable[] sds = null;
		try {
			sds = new ShapeDrawable[1];
			sds[0] = createRect();
			sds[0].getPaint().setColor(color);
			sds[0].setBounds(rect);
		} catch (Exception e) {
			sds = null;
		}
		return sds;
	}

	/**
	 * styleIndex=’1’ -- 圆角框，外框线带有颜色渐变。
	 * 
	 * @param color
	 * @param borderColor
	 * @param rect
	 * @return
	 */
	private static final ShapeDrawable[] roundRectWithGradientBorder(int color, int borderColor, Rect rect) {
		ShapeDrawable[] sds = null;
		try {
			sds = new ShapeDrawable[2];
			sds[0] = createRoundRect();
			sds[0].getPaint().setColor(color);
			sds[0].setBounds(rect);
			sds[1] = createRoundGradientBorder();
			sds[1].getPaint().setShader(makeLinearGradient(0, 0, 0, rect.bottom - rect.top, new int[] { borderColor, 0xFFFFFFFF }));
			sds[1].setBounds(rect);
		} catch (Exception e) {
			sds = null;
		}
		return sds;
	}

	/**
	 * styleIndex=’2’ -- 普通圆角框
	 * 
	 * @param color
	 * @param rect
	 * @return
	 */
	private static final ShapeDrawable[] roundRect(int color, Rect rect) {
		ShapeDrawable[] sds = null;
		try {
			sds = new ShapeDrawable[1];
			sds[0] = createRoundRect();
			sds[0].getPaint().setColor(color);
			sds[0].setBounds(rect);
		} catch (Exception e) {
			sds = null;
		}
		return sds;
	}

	/**
	 * styleIndex=’3’ -- 圆角框，边框内侧带有颜色渐变，视觉上有下凹感觉
	 * 
	 * @param color
	 * @param unfocusColor
	 * @param borderColor2
	 * @param rect
	 * @return
	 */
	private static final ShapeDrawable[] roundRectConcave(int color, int borderColor2, Rect rect) {
		ShapeDrawable[] sds = null;
		try {
			sds = new ShapeDrawable[1];
			sds[0] = createRoundRect();
			sds[0].getPaint().setColor(color);
			sds[0].setBounds(rect);
		} catch (Exception e) {
			sds = null;
		}
		return sds;
	}

	/**
	 * styleIndex=’4’ -- 圆角框，框内背景色有渐变，视觉上有凸起感觉
	 * 
	 * @param color
	 * @param unfocusColor
	 * @param bottom
	 * @return
	 */
	private static final Drawable[] roundRectGradient(int color, Rect rect) {
		Drawable[] sds = null;
		try {
			sds = new Drawable[1];
			GradientDrawable grad1 = new GradientDrawable(Orientation.TOP_BOTTOM, new int[] { Color.WHITE, color });
			grad1.setBounds(rect);
			grad1.setShape(GradientDrawable.RECTANGLE);
			grad1.setCornerRadius(CORNER_RADIUS);
			sds[0] = grad1;
		} catch (Exception e) {
			sds = null;
		}
		return sds;
	}

	/**
	 * styleIndex=’5’ -- 圆角框，框内背景色有渐变，颜色渐变没有5柔和，会以框的中线为分割，有明显得颜色变化，视觉上有凸起感觉
	 * 
	 * @param color
	 * @param unfocusColor
	 * @param height
	 * @return
	 */
	private static final Drawable[] roundRectStereo(int color, Rect rect) {
		Drawable[] sds = null;
		try {
			sds = new Drawable[3];
			ShapeDrawable sd = createRoundRect();
			sd.getPaint().setColor(color);
			sd.setBounds(rect);
			sds[0] = sd;
			// set Rect
			int height = rect.bottom - rect.top;
			Rect rectTop = new Rect(rect.left, rect.top, rect.right, rect.top + (int) (height * locations_[0]));
			Rect rectBottom = new Rect(rect.left, rect.top + (int) (height * locations_[1]), rect.right, rect.bottom);
			float[] roundRadiTop_ = new float[] { CORNER_RADIUS, CORNER_RADIUS, CORNER_RADIUS, CORNER_RADIUS, 0, 0, 0,
					0 };
			float[] roundRadiBottom_ = new float[] { 0, 0, 0, 0, CORNER_RADIUS, CORNER_RADIUS, CORNER_RADIUS, CORNER_RADIUS };
			// 顶部渐变
			GradientDrawable gradMaskTop = new GradientDrawable(Orientation.TOP_BOTTOM, alphaTop_);
			gradMaskTop.setBounds(rectTop);
			gradMaskTop.setShape(GradientDrawable.RECTANGLE);
			gradMaskTop.setCornerRadii(roundRadiTop_);
			sds[1] = gradMaskTop;
			// 底部渐变
			GradientDrawable gradMaskBottom = new GradientDrawable(Orientation.TOP_BOTTOM, alphaBottom_);
			gradMaskBottom.setBounds(rectBottom);
			gradMaskBottom.setShape(GradientDrawable.RECTANGLE);
			gradMaskBottom.setCornerRadii(roundRadiBottom_);
			sds[2] = gradMaskBottom;
		} catch (Exception e) {
			sds = null;
		}
		return sds;
	}

	/**
	 * styleIndex=’6’ -- 圆角框，框内背景色有渐变，底部有阴影，视觉上有凸起感觉，整体感觉最立体的一种样式
	 * 
	 * @param color
	 * @param rect
	 * @param isPressedDown
	 * @return
	 */
	private static final Drawable[] roundRectStereoWithShader(int color, Rect rect, boolean isPressedDown) {
		Drawable[] sds = null;
		try {
			ShapeDrawable outShader = createRoundRect();
			outShader.getPaint().setColor(SHADER_COLOR);
			Rect rectShader = new Rect(rect.left + SHADOW_HOR_OFFSET, rect.top + SHADOW_VER_OFFSET, rect.right, rect.bottom);
			outShader.setBounds(rectShader);
			Drawable[] other1 = null;
			if (isPressedDown) {
				other1 = roundRectStereo(color, rectShader);
			} else {
				other1 = roundRectStereo(color, new Rect(rect.left, rect.top, rect.right - SHADOW_HOR_OFFSET, rect.bottom - SHADOW_VER_OFFSET));
			}
			sds = new Drawable[1 + other1.length];
			sds[0] = outShader;
			for (int i = 0; i < other1.length; i++) {
				sds[i + 1] = other1[i];
			}
		} catch (Exception e) {
			sds = null;
		}
		return sds;
	}

	private final static ShapeDrawable createRect() {
		return new ShapeDrawable(new RectShape());
	}

	private final static ShapeDrawable createRoundRect() {
		float[] outerRoundRect = new float[8];
		for (int i = 0; i < 8; i++) {
			outerRoundRect[i] = CORNER_RADIUS;
		}
		return new ShapeDrawable(new RoundRectShape(outerRoundRect, null, null));
	}

	private final static ShapeDrawable createRoundGradientBorder() {
		// inner border Rectangle.
		RectF inner = new RectF(HORIZONTAL_BORDER, VERTICAL_BORDER, HORIZONTAL_BORDER, VERTICAL_BORDER);
		// outer RoundRectangle.
		float[] outerRoundRect = new float[8];
		for (int i = 0; i < 8; i++) {
			outerRoundRect[i] = CORNER_RADIUS;
		}
		// inner RoundRectangle.
		float[] innerRoundRect = new float[8];
		for (int i = 0; i < 8; i++) {
			innerRoundRect[i] = CORNER_RADIUS;
		}
		return new ShapeDrawable(new RoundRectShape(outerRoundRect, inner, innerRoundRect));
	}


	private final static Shader makeLinearGradient(float startX, float startY, float endX, float endY, int[] colors) {
		return new LinearGradient(startX, startY, endX, endY, colors, null, Shader.TileMode.CLAMP);
	}

}
